#include "../../include/keyparse.h"
#include "../../include/preprocess.h"
#include "../../include/grouping.h"
#include "../../include/matching.h"
#include "../../include/generation.h"

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

// 全局日志回调函数
static KeyParseLogCallback log_callback = NULL;

// 内部日志函数
static void log_message(KeyParseLogLevel level, const char* format, ...) {
    if (log_callback) {
        char buffer[1024];
        va_list args;
        va_start(args, format);
        vsnprintf(buffer, sizeof(buffer), format, args);
        va_end(args);
        log_callback(level, buffer);
    }
}

// CSV转义辅助函数
static char* escape_csv(const char* str) {
    if (!str) return NULL;
    
    // 检查是否需要转义
    int needs_escaping = 0;
    for (const char* p = str; *p; p++) {
        if (*p == '"' || *p == ',' || *p == '\n' || *p == '\r') {
            needs_escaping = 1;
            break;
        }
    }
    
    if (!needs_escaping) return NULL;
    
    // 计算需要转义的字符数
    int escape_count = 0;
    for (const char* p = str; *p; p++) {
        if (*p == '"') escape_count++;
    }
    
    // 分配足够的内存
    char* result = malloc(strlen(str) + escape_count + 3);
    if (!result) return NULL;
    
    char* dst = result;
    *dst++ = '"';
    
    for (const char* p = str; *p; p++) {
        if (*p == '"') {
            *dst++ = '"';
            *dst++ = '"';
        } else {
            *dst++ = *p;
        }
    }
    
    *dst++ = '"';
    *dst = '\0';
    
    return result;
}

// 初始化函数
KeyParseHandle keyparse_init() {
    GroupManager* gm = group_manager_init();
    if (!gm) {
        log_message(KEYPARSE_LOG_ERROR, "Failed to initialize group manager");
    }
    return gm;
}

// 处理单条日志
KeyParseError keyparse_process(KeyParseHandle handle, const char* log_line, 
                              char** group_key, char** template_str) {
    if (!handle || !log_line) {
        return KEYPARSE_ERROR_INVALID_INPUT;
    }
    
    GroupManager* gm = (GroupManager*)handle;
    
    log_message(KEYPARSE_LOG_DEBUG, "Processing log: %s", log_line);
    
    // 预处理日志消息
    char* preprocessed = preprocess_log(log_line);
    if (!preprocessed) {
        log_message(KEYPARSE_LOG_ERROR, "Preprocessing failed for: %s", log_line);
        return KEYPARSE_ERROR_PREPROCESS_FAILED;
    }
    
    log_message(KEYPARSE_LOG_DEBUG, "Preprocessed: %s", preprocessed);
    
    // 分词
    uint32_t token_count = 0;
    char** tokens = tokenize_string(preprocessed, &token_count);
    if (!tokens) {
        free(preprocessed);
        log_message(KEYPARSE_LOG_ERROR, "Tokenization failed for: %s", log_line);
        return KEYPARSE_ERROR_TOKENIZATION_FAILED;
    }
    
    log_message(KEYPARSE_LOG_DEBUG, "Token count: %u", token_count);
    
    // 处理分组
    int group_id = group_manager_process(gm, (const char**)tokens, token_count);
    if (group_id < 0) {
        free(preprocessed);
        free_tokens(tokens, token_count);
        log_message(KEYPARSE_LOG_ERROR, "Grouping failed for: %s", log_line);
        return KEYPARSE_ERROR_GROUPING_FAILED;
    }
    
    log_message(KEYPARSE_LOG_DEBUG, "Group ID: %d", group_id);
    
    // 获取分组
    TemplateGroup* group = group_manager_get_group(gm, group_id);
    if (!group) {
        free(preprocessed);
        free_tokens(tokens, token_count);
        log_message(KEYPARSE_LOG_ERROR, "Failed to get group for ID: %d", group_id);
        return KEYPARSE_ERROR_GROUPING_FAILED;
    }
    
    // 模板匹配和生成
    GenerationOptions options = generation_options_default();
    int template_index = process_template_generation(gm, group_id, (const char**)tokens, token_count, options);
    
    free(preprocessed);
    free_tokens(tokens, token_count);
    
    if (template_index < 0) {
        log_message(KEYPARSE_LOG_ERROR, "Template generation failed for: %s", log_line);
        return KEYPARSE_ERROR_TEMPLATE_GENERATION_FAILED;
    }
    
    log_message(KEYPARSE_LOG_DEBUG, "Template index: %d", template_index);
    
    // 获取组键和模板字符串
    const char* gk = group->group_key;
    const char* ts = group->templates[template_index]->template_str;
    
    // 分配内存并复制字符串
    *group_key = strdup(gk);
    *template_str = strdup(ts);
    
    if (!*group_key || !*template_str) {
        // 分配失败，释放可能已分配的内存
        free(*group_key);
        free(*template_str);
        log_message(KEYPARSE_LOG_ERROR, "Memory allocation failed");
        return KEYPARSE_ERROR_MEMORY_ALLOCATION;
    }
    
    log_message(KEYPARSE_LOG_DEBUG, "Group key: %s", *group_key);
    log_message(KEYPARSE_LOG_DEBUG, "Template: %s", *template_str);
    
    return KEYPARSE_SUCCESS;
}

// 批量处理日志文件
int keyparse_process_file(KeyParseHandle handle, const char* input_file, 
                         const char* output_file) {
    if (!handle || !input_file || !output_file) {
        return -1;
    }
    
    FILE* file = fopen(input_file, "r");
    if (!file) {
        log_message(KEYPARSE_LOG_ERROR, "Failed to open input file: %s", input_file);
        return -1;
    }
    
    FILE* out_file = fopen(output_file, "w");
    if (!out_file) {
        fclose(file);
        log_message(KEYPARSE_LOG_ERROR, "Failed to open output file: %s", output_file);
        return -1;
    }
    
    // 写入CSV表头
    fprintf(out_file, "GroupKey,Template,OriginalLog\n");
    
    char* line = NULL;
    size_t len = 0;
    ssize_t read;
    int processed_count = 0;
    int success_count = 0;
    
    log_message(KEYPARSE_LOG_INFO, "Starting file processing: %s -> %s", input_file, output_file);
    
    while ((read = getline(&line, &len, file)) != -1) {
        // 去除换行符
        if (read > 0 && line[read - 1] == '\n') {
            line[read - 1] = '\0';
        }
        
        char* group_key = NULL;
        char* template_str = NULL;
        
        KeyParseError ret = keyparse_process(handle, line, &group_key, &template_str);
        if (ret == KEYPARSE_SUCCESS) {
            // CSV转义处理
            char* escaped_group_key = escape_csv(group_key);
            char* escaped_template = escape_csv(template_str);
            char* escaped_log = escape_csv(line);
            
            fprintf(out_file, "%s,%s,%s\n",
                    escaped_group_key ? escaped_group_key : group_key,
                    escaped_template ? escaped_template : template_str,
                    escaped_log ? escaped_log : line);
            
            if (escaped_group_key) free(escaped_group_key);
            if (escaped_template) free(escaped_template);
            if (escaped_log) free(escaped_log);
            
            success_count++;
            
            if (success_count % 1000 == 0) {
                log_message(KEYPARSE_LOG_INFO, "Processed %d logs successfully", success_count);
            }
        } else {
            log_message(KEYPARSE_LOG_WARNING, "Failed to process log: %s (error: %s)", 
                       line, keyparse_error_message(ret));
        }
        
        // 释放内存
        if (group_key) free(group_key);
        if (template_str) free(template_str);
        
        processed_count++;
    }
    
    free(line);
    fclose(file);
    fclose(out_file);
    
    log_message(KEYPARSE_LOG_INFO, "File processing completed. Success: %d/%d", 
               success_count, processed_count);
    
    return success_count;
}

// 释放资源
void keyparse_free(KeyParseHandle handle) {
    if (handle) {
        group_manager_free((GroupManager*)handle);
        log_message(KEYPARSE_LOG_DEBUG, "KeyParse handle freed");
    }
}

// 释放字符串内存
void keyparse_free_string(char* str) {
    free(str);
}

// 设置日志回调函数
void keyparse_set_log_callback(KeyParseLogCallback callback) {
    log_callback = callback;
}

// 获取错误信息
const char* keyparse_error_message(KeyParseError error) {
    switch (error) {
        case KEYPARSE_SUCCESS: return "Success";
        case KEYPARSE_ERROR_INIT_FAILED: return "Initialization failed";
        case KEYPARSE_ERROR_INVALID_INPUT: return "Invalid input";
        case KEYPARSE_ERROR_PREPROCESS_FAILED: return "Preprocessing failed";
        case KEYPARSE_ERROR_TOKENIZATION_FAILED: return "Tokenization failed";
        case KEYPARSE_ERROR_GROUPING_FAILED: return "Grouping failed";
        case KEYPARSE_ERROR_TEMPLATE_GENERATION_FAILED: return "Template generation failed";
        case KEYPARSE_ERROR_MEMORY_ALLOCATION: return "Memory allocation failed";
        case KEYPARSE_ERROR_FILE_OPERATION: return "File operation failed";
        default: return "Unknown error";
    }
}